package com.ansion.adapter.list;

import android.util.SparseArray;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import androidx.annotation.NonNull;
import androidx.recyclerview.widget.AsyncDifferConfig;
import androidx.recyclerview.widget.DiffUtil;
import androidx.recyclerview.widget.RecyclerView;

import com.ansion.adapter.IAdapterData;
import com.ansion.view.pin_view.PinnedHeaderListAdapter;

import java.util.List;

/**
 * 对应的manager使用:
 * SafelyLinearLayoutManager
 * SafelyGridLayoutManager
 *
 * @param <T>
 */
public class TurboListAdapter<T extends IAdapterData, VH extends TurboListAdapter.ViewHolder<T>> extends PinnedHeaderListAdapter<T, VH> {

    private final SparseArray<ITurboListItem<T, VH>> mTypeCache = new SparseArray<>();

    protected TurboListAdapter(@NonNull DiffUtil.ItemCallback<T> diffCallback) {
        super(diffCallback);
    }

    protected TurboListAdapter(@NonNull AsyncDifferConfig<T> config) {
        super(config);
    }

    public static <T extends IAdapterData, VH extends BaseViewHolder<T>> TurboListAdapter<T, VH> with(@NonNull List<ITurboListItem<T, VH>> adapters,
                                                                                                                   @NonNull DiffUtil.ItemCallback<T> diffCallback) {
        TurboListAdapter<T, VH> adapter = new TurboListAdapter<>(diffCallback);
        for (ITurboListItem<T, VH> item : adapters) {
            adapter.saveType(item.getType(), item);
        }

        return adapter;
    }

    private void saveType(int key, ITurboListItem<T, VH> item) {
        mTypeCache.put(key, item);
    }

    @SuppressWarnings("unchecked")
    @NonNull
    @Override
    public VH onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        ITurboListItem<T, VH> viewHolderITurboListItem = mTypeCache.get(viewType);
        if (viewHolderITurboListItem == null) {
            return (VH) new EmptyVH(new TextView(parent.getContext()));
        }

        return viewHolderITurboListItem.getVH(parent);
    }

    @Override
    public void onBindViewHolder(@NonNull VH holder, int position) {
        holder.bindView(getItem(position), position);
    }

    @Override
    public void onBindViewHolder(@NonNull VH holder, int position, @NonNull List<Object> payloads) {
        holder.bindView(getItem(position), position, payloads);
    }

    @Override
    public int getItemViewType(int position) {
        return getCurrentList().get(position).getType();
    }

    @Override
    public boolean isPinnedPosition(int position) {
        return getItemViewType(position) == PIN_TYPE;
    }

    class EmptyVH extends ViewHolder<T> {

        public EmptyVH(View itemView) {
            super(itemView);
        }

        @Override
        public void bindView(T item, int position) {

        }
    }

    abstract static class ViewHolder<T extends IAdapterData> extends RecyclerView.ViewHolder {
        public ViewHolder(View itemView) {
            super(itemView);
        }

        public abstract void bindView(T item, int position);

        public void bindView(T item, int position, @NonNull List<Object> payloads) {
            bindView(item, position);
        }
    }

    public abstract static class BaseViewHolder<T extends IAdapterData> extends ViewHolder<T> {

        public BaseViewHolder(View itemView) {
            super(itemView);
        }
    }
}
